package main

import "fmt"

// channel 与 select的配合使用
/**
  1、正常情况下，单流程下的一个go只能监听一个channel的状态
  2、而select可以完成监听多个channel的状态，很像java中nio的多路复用器
*/

/** 代码执行结果：
  1
  2
  4
  8
  16
  32
  64
  128
  256
  512
  quit
*/
func main() {
	c := make(chan int)
	quit := make(chan int)

	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c) // 从管道c中读取数据并打印出来
		}
		quit <- 0 // for循环结束后，往quit中发送一个0退出
	}()

	// 现在同时监控 c 和 quit 两个管道的状态
	fibonacii(c, quit)
}

// 这个方法的目的是，刚开始往c中不断地写变化的y值，执行6次后，由goroutine往quit中写入一个0，触发程序的退出
func fibonacii(c, quit chan int) {
	x, y := 1, 1

	for true {
		select {
		case c <- y: // 判断c是否可写，顺便会把y写入到c中
			// 随便写的一个公式，没有特殊的意思
			x = y
			y = x + y
		case <-quit: // 判断quit是否可读，在goroutine写入0之前，quit是阻塞状态的
			fmt.Println("quit")
			return
		}
	}
}
